/**
 * Wrapper class for the google route service.
 * 
 * @author Kim Pommert
 * @version %I%, %G%
 */
qx.Class.define("qooxdoosample.google.maps.GRoutePlanner",
{
	extend:  qx.core.Object,
	implement: qooxdoosample.cocktail.maps.IRoutePlanner,
	
	/**
	 * Class constructor.
	 * Instantiates an object of that class.
	 */
	construct: function()
	{
		this.base(arguments);
		this.setGRoute(new GDirections(null, null));
		this.setTravelMode(0);
	},
	
	statics:
	{
		/**
		 * Constant for the driving travel mode.
		 * The calculated route will only use roads 
		 * and locations that can be reached by car.
		 */
		TRAVEL_MODE_DRIVING: 0,
		
		/**
		 * Constant for the walking travel mode.
		 * The calculated route will only use roads
		 * and locations that can be reached by walking.
		 */
		TRAVEL_MODE_WALKING: 1
	},
	
	properties:
	{
		/**
    	 * Googles routing object.
    	 * All method calls will be converted and sent to this object.
		 */
		gRoute:
		{
			nullable: true,
			init: null,
			check: "GDirections"
		},
		
		/**
		 * Travel mode of the route.
		 */
		travelMode:
		{
			nullable: false,
			init: 0,
			check: [0, 1]
		}
	},
	
	members:
	{				
		/**
		 * Get a complete route from start to target point.
		 * The result provides a Polyline representation 
		 * and a step by step description of the route.
		 * 
		 * @param start		{String} The location/address of the start point
		 * @param target 	{String} The location/address of the end point
		 * @param callback 	{Function} The result will be sent to this callback function
		 * @see qooxdoosample.cocktail.maps.IRoutePlanner#getRoute()
		 */
		getRoute: function(start, target, callback)
		{
			gdir = this.getGRoute();
  			 	
  			GEvent.addListener(gdir, "error", function(e){
    			if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
    				alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + gdir.getStatus().code);
  				else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
    				alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
  				else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
    				alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);
  				else if (gdir.getStatus().code == G_GEO_BAD_KEY)
    				alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);
  				else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
    				alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);
  				else alert("An unknown error occurred.");
    		});		
    		
    		GEvent.addListener(gdir, "load", function(e){
    			
    			if(gdir.getStatus().code == 200){
    				
    				// load polyline from result 			
    				var gLine = gdir.getPolyline();
    				var gPoint = null;
    				var point = null;
    				var pointsArr = new Array();
    				
    				for(i = 0; i < gLine.getVertexCount(); i++){
    					gPoint = gLine.getVertex(i);
    					point = new qooxdoosample.cocktail.util.LatLng(gPoint.lat(), gPoint.lng());
    					pointsArr[i] = point;
    				}
    				
    				var polyline = new qooxdoosample.cocktail.util.overlays.Polyline(pointsArr);
    				
    				// load route steps from result
    				var gRoute = gdir.getRoute(0);
    				var gStep = null;
    				var step = null;
    				var gPosition = null;
    				var position = null;
    				var stepsArr = new Array();
    				
    				for(i = 0; i < gRoute.getNumSteps(); i++){
    					gStep = gRoute.getStep(i);
    					gPosition = gStep.getLatLng();
    					position = new qooxdoosample.cocktail.util.LatLng(gPosition.lat(), gPosition.lng());
    					
    					step = new qooxdoosample.cocktail.util.Step(position);
    					step.setDescription(gStep.getDescriptionHtml());
    					step.setDistance(gStep.getDistance().meters);
    					step.setDuration(gStep.getDuration().seconds);
    					stepsArr[i] = step;
    				}
    				
    				
    				var route = new qooxdoosample.cocktail.util.Route(polyline);
    				route.setSteps(stepsArr);
    				
    				route.setDistance(gRoute.getDistance().meters);
    				route.setDuration(gRoute.getDuration().seconds);
    				
    				callback(route);
    			}
    			
    		});

			var options = { locale: "de_DE" , getSteps:true, getPolyline:true };
			
			// set the travel mode
			if(this.getTravelMode() == this.self(arguments).TRAVEL_MODE_WALKING)
				options.travelMode = G_TRAVEL_MODE_WALKING;
			else
				options.travelMode = G_TRAVEL_MODE_DRIVING;

			// start and target can either be Strings representing an address
			// or a LatLng object
			if(start instanceof qooxdoosample.cocktail.util.LatLng)
			{
				var startPoint = start.getLatitude() + ", " + start.getLongitude();
				var targetPoint = target.getLatitude() + ", " + target.getLongitude();
				gdir.load("from: " + startPoint + " to: " + targetPoint, options);
			}
			else
			{
	 			gdir.load("from: " + start + " to: " + target, options);
			}
  			
			
		}
		
		
	}
	
});